/*
 * dioPacketHandler.h
 *
 * Created: 9/20/2013 1:31:11 AM
 *  Author: Tim
 */ 


#ifndef DIOPACKETHANDLER_H_
#define DIOPACKETHANDLER_H_

#include "../../features/allocations.h"
#include "../structs/dioPacketStructs.h"
#include "genPacketHandler.h"
#include "../status.h"

static inline status_t digitalInEnableHandler(digitalInEnable_t *packet)
{
	uint8_t i;
	
	for(i=0;i<13;i++)
	{
		if(i<8){
			if(packet->dataL & 1<<i)
			{
				if(daqAlloc.dio[i].alloc == FEATURE_FREE)
				{
					daqAlloc.dio[i].source	= DIO_INPUT;
					daqAlloc.dio[i].alloc	= FEATURE_UTILIZED;
					dioDirClr(i);
					sendGenAck(digitalInEnable_mh,i);
				}
				else
				{
					//send bad ack
					sendGenAck(digitalInEnable_mh,0x80 | i);
				}
			}
			else if(daqAlloc.dio[i].alloc == FEATURE_UTILIZED && daqAlloc.dio[i].source == DIO_INPUT)
			{
				//release pin from use
				daqAlloc.dio[i].alloc = FEATURE_FREE;
				daqAlloc.dio[i].source = DIO_FREE;
			}
		}
		else if(i < 13)
		{
			if(packet->dataH & 1<<(i-8))
			{
				
				if(daqAlloc.dio[i].alloc == FEATURE_FREE)
				{
					daqAlloc.dio[i].source	= DIO_INPUT;
					daqAlloc.dio[i].alloc	= FEATURE_UTILIZED;
					dioDirClr(i);
					sendGenAck(digitalInEnable_mh,i);
				}
				else
				{
					//send bad ack
					sendGenAck(digitalInEnable_mh,0x80 | i);
				}
				
			}
			else if(daqAlloc.dio[i].alloc == FEATURE_UTILIZED && daqAlloc.dio[i].source == DIO_INPUT)
			{
				//release pin from use
				daqAlloc.dio[i].alloc = FEATURE_FREE;
				daqAlloc.dio[i].source = DIO_FREE;
			}
		}
	}
	
	for(i=0;i<13;i++)
	{
		if(daqAlloc.dio[i].alloc == FEATURE_UTILIZED && daqAlloc.dio[i].source == DIO_INPUT)
		{
			//if digital in is already enabled and it still is exit
			if(daqAlloc.digitalIn == FEATURE_UTILIZED)return OPP_SUCCESSFUL;
			//if digital in is now enabled, but should be, enable and augment the super packet length
			else if(daqAlloc.digitalIn == FEATURE_FREE)
			{
				daqAlloc.digitalIn = FEATURE_UTILIZED;
				outputSuperPacketLength += 4;
				return OPP_SUCCESSFUL;
			}
		}
	}
	
	//no input pins were set
	return OPP_FAILED;

}

static inline status_t digitalOutEnableHandler(digitalOutEnable_t *packet)
{
	uint8_t i;
	
	for(i=0;i<13;i++)
	{
		if(i<8){
			if(packet->dataL & 1<<i)
			{
				if(daqAlloc.dio[i].alloc == FEATURE_FREE)
				{
					daqAlloc.dio[i].source	= DIO_OUTPUT;
					daqAlloc.dio[i].alloc	= FEATURE_UTILIZED;
					dioDirSet(i);
					sendGenAck(digitalOutEnable_mh,i);
				}
				else
				{
					//send bad ack
					sendGenAck(digitalOutEnable_mh,0x80 | i);
				}
			}
			else if(daqAlloc.dio[i].alloc == FEATURE_UTILIZED && daqAlloc.dio[i].source == DIO_OUTPUT)
			{
				//release pin from use
				daqAlloc.dio[i].alloc = FEATURE_FREE;
				daqAlloc.dio[i].source = DIO_FREE;
			}
		}
		else if(i < 13)
		{
			if(packet->dataH & 1<<(i-8))
			{
				
				if(daqAlloc.dio[i].alloc == FEATURE_FREE)
				{
					daqAlloc.dio[i].source	= DIO_OUTPUT;
					daqAlloc.dio[i].alloc	= FEATURE_UTILIZED;
					dioDirSet(i);
					sendGenAck(digitalOutEnable_mh,i);
				}
				else
				{
					//send bad ack
					sendGenAck(digitalOutEnable_mh,0x80 | i);
				}
				
			}
			else if(daqAlloc.dio[i].alloc == FEATURE_UTILIZED && daqAlloc.dio[i].source == DIO_OUTPUT)
			{
				//release pin from use
				daqAlloc.dio[i].alloc = FEATURE_FREE;
				daqAlloc.dio[i].source = DIO_FREE;
			}
		}
	}
	
	for(i=0;i<13;i++)
	{
		if(daqAlloc.dio[i].alloc == FEATURE_UTILIZED && daqAlloc.dio[i].source == DIO_OUTPUT)
		{
			//if digital in is already enabled and it still is exit
			if(daqAlloc.digitalOut == FEATURE_UTILIZED)return OPP_SUCCESSFUL;
			//if digital in is now enabled, but should be, enable and augment the super packet length
			else if(daqAlloc.digitalOut == FEATURE_FREE)
			{
				daqAlloc.digitalOut = FEATURE_UTILIZED;
				outputSuperPacketLength += 4;
				return OPP_SUCCESSFUL;
			}
		}
	}
	
	//no input pins were set
	return OPP_FAILED;
}


#endif /* DIOPACKETHANDLER_H_ */